<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">

<head>
    <!-- Book generated using mdBook -->
    <meta charset="UTF-8">
    <title>十进制 - exercisms.io 快速练习</title>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta name="description" content="exercisms 的练习，网页版.">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="theme-color" content="#ffffff" />

    <link rel="shortcut icon" href="../favicon.png">
    <link rel="stylesheet" href="../css/variables.css">
    <link rel="stylesheet" href="../css/general.css">
    <link rel="stylesheet" href="../css/chrome.css">
    <link rel="stylesheet" href="../css/print.css" media="print">

    <!-- Fonts -->
    <link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
        rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">

    <!-- Highlight.js Stylesheets -->
    <link rel="stylesheet" href="../highlight.css">
    <link rel="stylesheet" href="../tomorrow-night.css">
    <link rel="stylesheet" href="../ayu-highlight.css">

    <!-- Custom theme stylesheets -->
    
    <link rel="stylesheet" href="../theme/custom.css">
    

    
</head>

<body class="light">
    <!-- Provide site root to javascript -->
    <script type="text/javascript">var path_to_root = "../";</script>

    <!-- Work around some values being stored in localStorage wrapped in quotes -->
    <script type="text/javascript">
        try {
            var theme = localStorage.getItem('mdbook-theme');
            var sidebar = localStorage.getItem('mdbook-sidebar');

            if (theme.startsWith('"') && theme.endsWith('"')) {
                localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
            }

            if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
            }
        } catch (e) { }
    </script>

    <!-- Set the theme before any content is loaded, prevents flash -->
    <script type="text/javascript">
        var theme;
        try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
        if (theme === null || theme === undefined) { theme = 'light'; }
        document.body.className = theme;
        document.querySelector('html').className = theme + ' js';
    </script>

    <!-- Hide / unhide sidebar before it is displayed -->
    <script type="text/javascript">
        var html = document.querySelector('html');
        var sidebar = 'hidden';
        if (document.body.clientWidth >= 1080) {
            try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch (e) { }
            sidebar = sidebar || 'visible';
        }
        html.classList.remove('sidebar-visible');
        html.classList.add("sidebar-" + sidebar);
    </script>

    <nav id="sidebar" class="sidebar" aria-label="Table of contents">
        <ol class="chapter"><li><a href="../index.html"><strong aria-hidden="true">1.</strong> 超过 88 道练习，任点</a></li><li><a href="../low.html"><strong aria-hidden="true">2.</strong> 易</a></li><li><ol class="section"><li><a href="../hello-world/README.zh.html"><strong aria-hidden="true">2.1.</strong> hello world</a></li><li><a href="../gigasecond/README.zh.html"><strong aria-hidden="true">2.2.</strong> 千兆秒 &gt;&lt; Gigasecond)</a></li><li><a href="../leap/README.zh.html"><strong aria-hidden="true">2.3.</strong> 闰年 &gt;&lt; Leap</a></li><li><a href="../raindrops/README.zh.html"><strong aria-hidden="true">2.4.</strong> 雨滴声 &gt;&lt; Raindrops</a></li><li><a href="../reverse-string/README.zh.html"><strong aria-hidden="true">2.5.</strong> 反转字符串 &gt;&lt; Reverse String</a></li><li><a href="../nth-prime/README.zh.html"><strong aria-hidden="true">2.6.</strong> 第 n 个素数 &gt;&lt; Nth Prime</a></li><li><a href="../bob/README.zh.html"><strong aria-hidden="true">2.7.</strong> 迟钝孩子 &gt;&lt; Bob</a></li><li><a href="../beer-song/README.zh.html"><strong aria-hidden="true">2.8.</strong> 啤酒之歌 &gt;&lt; Beer Song</a></li><li><a href="../proverb/README.zh.html"><strong aria-hidden="true">2.9.</strong> 谚语串烧 &gt;&lt; Proverb</a></li><li><a href="../difference-of-squares/README.zh.html"><strong aria-hidden="true">2.10.</strong> 平方差 &gt;&lt; Difference Of Squares</a></li><li><a href="../sum-of-multiples/README.zh.html"><strong aria-hidden="true">2.11.</strong> 倍数之和 &gt;&lt; Sum Of Multiples</a></li><li><a href="../grains/README.zh.html"><strong aria-hidden="true">2.12.</strong> 谷物 &gt;&lt; Grains</a></li><li><a href="../pythagorean-triplet/README.zh.html"><strong aria-hidden="true">2.13.</strong> 勾股数 &gt;&lt; Pythagorean Triplet</a></li><li><a href="../prime-factors/README.zh.html"><strong aria-hidden="true">2.14.</strong> 素数因子 &gt;&lt; Prime Factors</a></li><li><a href="../series/README.zh.html"><strong aria-hidden="true">2.15.</strong> 子串 &gt;&lt; Series</a></li><li><a href="../armstrong-numbers/README.zh.html"><strong aria-hidden="true">2.16.</strong> 水仙花数 &gt;&lt; Armstrong Numbers</a></li><li><a href="../collatz-conjecture/README.zh.html"><strong aria-hidden="true">2.17.</strong> 3n+1 猜想 &gt;&lt; Collatz Conjecture</a></li><li><a href="../diffie-hellman/README.zh.html"><strong aria-hidden="true">2.18.</strong> 迪菲-赫尔曼密钥交换 &gt;&lt; Diffie Hellman</a></li></ol></li><li><a href="../medium.html"><strong aria-hidden="true">3.</strong> 中等</a></li><li><ol class="section"><li><a href="../saddle-points/README.zh.html"><strong aria-hidden="true">3.1.</strong> 鞍点 &gt;&lt; Saddle Points</a></li><li><a href="../isogram/README.zh.html"><strong aria-hidden="true">3.2.</strong> 等值线 &gt;&lt; Isogram</a></li><li><a href="../say/README.zh.html"><strong aria-hidden="true">3.3.</strong> 英文说数字 &gt;&lt; Say</a></li><li><a href="../run-length-encoding/README.zh.html"><strong aria-hidden="true">3.4.</strong> 游程编码 &gt;&lt; Run Length Encoding</a></li><li><a href="../isbn-verifier/README.zh.html"><strong aria-hidden="true">3.5.</strong> 图书编号 &gt;&lt; ISBN Verifier</a></li><li><a href="../perfect-numbers/README.zh.html"><strong aria-hidden="true">3.6.</strong> 数字也能分类 &gt;&lt; Perfect Numbers</a></li><li><a href="../clock/README.zh.html"><strong aria-hidden="true">3.7.</strong> 时钟 &gt;&lt; Clock</a></li><li><a href="../dot-dsl/README.zh.html"><strong aria-hidden="true">3.8.</strong> DOT DSL</a></li><li><a href="../hamming/README.zh.html"><strong aria-hidden="true">3.9.</strong> 汉明距离 &gt;&lt; Hamming</a></li><li><a href="../simple-linked-list/README.zh.html"><strong aria-hidden="true">3.10.</strong> 简单链表 &gt;&lt; Simple Linked List</a></li><li><a href="../pascals-triangle/README.zh.html"><strong aria-hidden="true">3.11.</strong> 杨辉三角形 &gt;&lt; Pascal's Triangle</a></li><li><a href="../scrabble-score/README.zh.html"><strong aria-hidden="true">3.12.</strong> 字母的分数游戏 &gt;&lt; Scrabble Score</a></li><li><a href="../pangram/README.zh.html"><strong aria-hidden="true">3.13.</strong> 全字母句 &gt;&lt; Pangram</a></li><li><a href="../paasio/README.zh.html"><strong aria-hidden="true">3.14.</strong> PaaS-IO-报告 &gt;&lt; Paasio</a></li><li><a href="../nucleotide-count/README.zh.html"><strong aria-hidden="true">3.15.</strong> 核苷酸计数 &gt;&lt; Nucleotide Count</a></li><li><a href="../luhn/README.zh.html"><strong aria-hidden="true">3.16.</strong> 模 10 算法 &gt;&lt; Luhn</a></li><li><a href="../largest-series-product/README.zh.html"><strong aria-hidden="true">3.17.</strong> 最大数字子串乘积 &gt;&lt; Largest Series Product</a></li><li><a href="../word-count/README.zh.html"><strong aria-hidden="true">3.18.</strong> 单词计数 &gt;&lt; Word Count</a></li><li><a href="../atbash-cipher/README.zh.html"><strong aria-hidden="true">3.19.</strong> Atbash 加密 &gt;&lt; Atbash Cipher</a></li><li><a href="../crypto-square/README.zh.html"><strong aria-hidden="true">3.20.</strong> 密码矩形 &gt;&lt; Crypto Square</a></li><li><a href="../rotational-cipher/README.zh.html"><strong aria-hidden="true">3.21.</strong> 旋转密码 &gt;&lt; Rotational Cipher</a></li><li><a href="../simple-cipher/README.zh.html"><strong aria-hidden="true">3.22.</strong> 简单加密 &gt;&lt; Simple Cipher</a></li><li><a href="../rail-fence-cipher/README.zh.html"><strong aria-hidden="true">3.23.</strong> 栅栏密码 &gt;&lt; Rail Fence Cipher</a></li><li><a href="../etl/README.zh.html"><strong aria-hidden="true">3.24.</strong> ETL</a></li><li><a href="../accumulate/README.zh.html"><strong aria-hidden="true">3.25.</strong> 集合操作 &gt;&lt; Accumulate</a></li><li><a href="../acronym/README.zh.html"><strong aria-hidden="true">3.26.</strong> 术语 &gt;&lt; Acronym</a></li><li><a href="../sieve/README.zh.html"><strong aria-hidden="true">3.27.</strong> 素数筛 &gt;&lt; Sieve</a></li><li><a href="../rna-transcription/README.zh.html"><strong aria-hidden="true">3.28.</strong> RNA 转录 &gt;&lt; RNA Transcription</a></li><li><a href="../triangle/README.zh.html"><strong aria-hidden="true">3.29.</strong> 三角形</a></li><li><a href="../roman-numerals/README.zh.html"><strong aria-hidden="true">3.30.</strong> 罗马数字 &gt;&lt; Roman Numerals</a></li><li><a href="../all-your-base/README.zh.html"><strong aria-hidden="true">3.31.</strong> 你所的基本</a></li><li><a href="../grade-school/README.zh.html"><strong aria-hidden="true">3.32.</strong> 学册</a></li><li><a href="../binary-search/README.zh.html"><strong aria-hidden="true">3.33.</strong> 二分查找</a></li><li><a href="../robot-simulator/README.zh.html"><strong aria-hidden="true">3.34.</strong> 机器人模拟器</a></li><li><a href="../bracket-push/README.zh.html"><strong aria-hidden="true">3.35.</strong> 括号配套</a></li><li><a href="../luhn-from/README.zh.html"><strong aria-hidden="true">3.36.</strong> Luhn From</a></li><li><a href="../queen-attack/README.zh.html"><strong aria-hidden="true">3.37.</strong> 皇后 攻击</a></li><li><a href="../bowling/README.zh.html"><strong aria-hidden="true">3.38.</strong> 保龄球</a></li><li><a href="../sublist/README.zh.html"><strong aria-hidden="true">3.39.</strong> 子列表</a></li><li><a href="../space-age/README.zh.html"><strong aria-hidden="true">3.40.</strong> 地球年</a></li><li><a href="../luhn-trait/README.zh.html"><strong aria-hidden="true">3.41.</strong> Luhn Trait</a></li><li><a href="../macros/README.zh.html"><strong aria-hidden="true">3.42.</strong> 宏</a></li><li><a href="../allergies/README.zh.html"><strong aria-hidden="true">3.43.</strong> 过敏</a></li><li><a href="../variable-length-quantity/README.zh.html"><strong aria-hidden="true">3.44.</strong> 可变长度数量</a></li><li><a href="../phone-number/README.zh.html"><strong aria-hidden="true">3.45.</strong> 电话号码</a></li><li><a href="../wordy/README.zh.html"><strong aria-hidden="true">3.46.</strong> 罗唆</a></li><li><a href="../tournament/README.zh.html"><strong aria-hidden="true">3.47.</strong> 比赛</a></li><li><a href="../custom-set/README.zh.html"><strong aria-hidden="true">3.48.</strong> 自定义 set</a></li><li><a href="../alphametics/README.zh.html"><strong aria-hidden="true">3.49.</strong> 字母谜题</a></li><li><a href="../two-bucket/README.zh.html"><strong aria-hidden="true">3.50.</strong> 两个桶</a></li><li><a href="../pig-latin/README.zh.html"><strong aria-hidden="true">3.51.</strong> 猪的拉丁文</a></li><li><a href="../diamond/README.zh.html"><strong aria-hidden="true">3.52.</strong> 钻石</a></li><li><a href="../spiral-matrix/README.zh.html"><strong aria-hidden="true">3.53.</strong> 螺旋矩阵</a></li><li><a href="../palindrome-products/README.zh.html"><strong aria-hidden="true">3.54.</strong> 回文产品</a></li><li><a href="../poker/README.zh.html"><strong aria-hidden="true">3.55.</strong> 扑克</a></li><li><a href="../grep/README.zh.html"><strong aria-hidden="true">3.56.</strong> grep</a></li><li><a href="../scale-generator/README.zh.html"><strong aria-hidden="true">3.57.</strong> 音阶生成器</a></li><li><a href="../decimal/README.zh.html" class="active"><strong aria-hidden="true">3.58.</strong> 十进制</a></li><li><a href="../anagram/README.zh.html"><strong aria-hidden="true">3.59.</strong> 字谜</a></li><li><a href="../protein-translation/README.zh.html"><strong aria-hidden="true">3.60.</strong> 蛋白质翻译</a></li><li><a href="../robot-name/README.zh.html"><strong aria-hidden="true">3.61.</strong> 机器人名称</a></li><li><a href="../book-store/README.zh.html"><strong aria-hidden="true">3.62.</strong> 书店</a></li></ol></li><li><a href="../high.html"><strong aria-hidden="true">4.</strong> 难</a></li><li><ol class="section"><li><a href="../ocr-numbers/README.zh.html"><strong aria-hidden="true">4.1.</strong> OCR 号码</a></li><li><a href="../minesweeper/README.zh.html"><strong aria-hidden="true">4.2.</strong> 扫雷</a></li><li><a href="../dominoes/README.zh.html"><strong aria-hidden="true">4.3.</strong> 骨牌</a></li><li><a href="../parallel-letter-frequency/README.zh.html"><strong aria-hidden="true">4.4.</strong> 并行字母频率</a></li><li><a href="../rectangles/README.zh.html"><strong aria-hidden="true">4.5.</strong> 矩形</a></li><li><a href="../forth/README.zh.html"><strong aria-hidden="true">4.6.</strong> Forth</a></li><li><a href="../circular-buffer/README.zh.html"><strong aria-hidden="true">4.7.</strong> 循环缓冲区</a></li><li><a href="../react/README.zh.html"><strong aria-hidden="true">4.8.</strong> React</a></li></ol></li><li><a href="../untag.html"><strong aria-hidden="true">5.</strong> 未标签</a></li><li><ol class="section"><li><a href="../hexadecimal/README.zh.html"><strong aria-hidden="true">5.1.</strong> 十六进制</a></li><li><a href="../nucleotide-codons/README.zh.html"><strong aria-hidden="true">5.2.</strong> 核苷酸密码子</a></li><li><a href="../two-fer/README.zh.html"><strong aria-hidden="true">5.3.</strong> two-fer</a></li><li class="spacer"></li></ol></li><li><a href="../add-test-code.html">修改 mdBook 主题</a></li></ol>
    </nav>

    <div id="page-wrapper" class="page-wrapper">

        <div class="page">
            
            <div id="menu-bar" class="menu-bar">
                <div id="menu-bar-sticky-container">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents"
                            aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <!-- START - Rust Cookbook customization -->
                        <button id="edit-button" class="icon-button" type="button" title="Fork and edit" aria-label="Fork and edit"
                            aria-haspopup="true" aria-expanded="false" aria-controls="edit">
                            <i class="fa fa-edit">Edit</i>
                        </button>
                        <!-- END - Rust Cookbook customization -->
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme"
                            aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)"
                            aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                        
                    </div>

                    <h1 class="menu-title">exercisms.io 快速练习</h1>
                    
                        <div class="right-buttons">
                            <a href="../print.html" title="Print this book" aria-label="Print this book">
                                <i id="print-button" class="fa fa-print"></i>
                            </a>
                            
                        </div>
                    </div>
                </div>

            
            <div id="search-wrapper" class="hidden">
                <form id="searchbar-outer" class="searchbar-outer">
                    <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..."
                        aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                </form>
                <div id="searchresults-outer" class="searchresults-outer hidden">
                    <div id="searchresults-header" class="searchresults-header"></div>
                    <ul id="searchresults">
                    </ul>
                </div>
            </div>
            

            <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
            <script type="text/javascript">
                document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                Array.from(document.querySelectorAll('#sidebar a')).forEach(function (link) {
                    link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                });
            </script>

            <!-- // START - Rust Cookbook customization -->
            <script>
                document.getElementById("edit-button").addEventListener("click", function () {
                    var editWindow = window.open("https://github.com/chinanf-boy/exercism-rust-zh/edit/master/src/decimal/README.zh.md");
                });</script>
            <!-- // END - Rust Cookbook customization -->

            <div id="content" class="content">
                <main>
                    <a class="header" href="#decimal" id="decimal"><h1>Decimal</h1></a>
<a class="header" href="#1-readme" id="1-readme"><h2>1. Readme</h2></a>
<a class="header" href="#十进制" id="十进制"><h1>十进制</h1></a>
<p>实现任意精度的<code>Decimal</code>类。</p>
<p>浮点数是计算中非整数实数的最常见表示，它们是由<a href="https://en.wikipedia.org/wiki/IEEE_754">IEEE 754</a>标准定义。它们非常灵活且通用，但它们确实有一些局限性。众所周知，在浮点运算中，<a href="http://0.30000000000000004.com/"><code>0.1 + 0.2 != 0.3</code></a>。</p>
<p>解决这一问题的方法是，寻找另一种无损的方法来模拟任意精度的非整数 实数。这可能在内存或处理速度方面，不如浮点数有效；但目标是提供准确的结果。</p>
<p>尽管<code>Decimal</code>作为一种自定义类型，我们仍然应该能够将它们视为数字: 而<code>==</code>，<code>&lt;</code>，<code>&gt;</code>，<code>+</code>，<code>-</code>和<code>*</code>操作符都应该按小数进行工作。只是权宜之计，你不需要执行除法，因为任意的精确除法很快就会失控。(如何表示任意精度<code>1/3</code>?)</p>
<p>在 Rust 中，将这些操作用于自定义类型的方法是，实现自定义对象的相关 trait。特别是，您至少需要实现.<code>PartialEq</code>，<code>PartialOrd</code>，<code>Add</code>，<code>Sub</code>和<code>Mul</code>。 严格地说，由于十进制数构成一个总排序，你也应该实现<code>Eq</code>和<code>Ord</code>，尽管这些 trait 并没有被这些测试所检验.</p>
<a class="header" href="#笔记" id="笔记"><h1>笔记</h1></a>
<p>使用这种.<a href="https://crates.io/crates/bigdecimal">bigdecimal</a>箱子方法很容易实现这个练习。但不要那样做，你自己来实现。</p>
<a class="header" href="#提示" id="提示"><h1>提示</h1></a>
<ul>
<li>不要从头开始执行任意精确的算术，而是考虑在<a href="https://crates.io/crates/num-bigint">num_bigint</a>箱子之上构建自己的类。</li>
<li>你也许能<a href="https://doc.rust-lang.org/book/appendix-03-derivable-traits.html">derive</a>一些需要的 trait。</li>
<li><code>Decimal</code>假设为符号类型。你不必创建一个单独的无符号类型，尽管你可以这样做，如果你选择这么样，能作为一个实现细节。</li>
</ul>
<a class="header" href="#资源" id="资源"><h2>资源</h2></a>
<p>Peter Goodspeed-Niklaus</p>
<a class="header" href="#2-开始你的表演" id="2-开始你的表演"><h2>2. 开始你的表演</h2></a>
<pre><pre class="playpen"><code class="language-rust editable">/// Type implementing arbitrary-precision decimal arithmetic
pub struct Decimal {
   // implement your type here
}

impl Decimal {
   pub fn try_from(input: &amp;str) -&gt; Option&lt;Decimal&gt; {
       unimplemented!(&quot;Create a new decimal with a value of {}&quot;, input)
   }
}

</code></pre></pre>
<a class="header" href="#3-测试代码查看" id="3-测试代码查看"><h2>3. 测试代码查看</h2></a>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
/// Create a Decimal from a string literal
///
/// Use only when you _know_ that your value is valid.
fn decimal(input: &amp;str) -&gt; Decimal {
   Decimal::try_from(input).expect(&quot;That was supposed to be a valid value&quot;)
}

/// Some big and precise values we can use for testing. [0] + [1] == [2]
const BIGS: [&amp;'static str; 3] = [
   &quot;100000000000000000000000000000000000000000000.00000000000000000000000000000000000000001&quot;,
   &quot;100000000000000000000000000000000000000000000.00000000000000000000000000000000000000002&quot;,
   &quot;200000000000000000000000000000000000000000000.00000000000000000000000000000000000000003&quot;,
];

// test simple properties of required operations
#[test]
fn test_eq() {
   assert!(decimal(&quot;0.0&quot;) == decimal(&quot;0.0&quot;));
   assert!(decimal(&quot;1.0&quot;) == decimal(&quot;1.0&quot;));
   for big in BIGS.iter() {
       assert!(decimal(big) == decimal(big));
   }
}

#[test]
//#[ignore]
fn test_ne() {
   assert!(decimal(&quot;0.0&quot;) != decimal(&quot;1.0&quot;));
   assert!(decimal(BIGS[0]) != decimal(BIGS[1]));
}

#[test]
//#[ignore]
fn test_gt() {
   for slice_2 in BIGS.windows(2) {
       assert!(decimal(slice_2[1]) &gt; decimal(slice_2[0]));
       assert!(!(decimal(slice_2[0]) &gt; decimal(slice_2[1])));
   }
}

#[test]
//#[ignore]
fn test_lt() {
   for slice_2 in BIGS.windows(2) {
       assert!(decimal(slice_2[0]) &lt; decimal(slice_2[1]));
       assert!(!(decimal(slice_2[1]) &lt; decimal(slice_2[0])));
   }
}

#[test]
//#[ignore]
fn test_add() {
   assert_eq!(decimal(&quot;0.1&quot;) + decimal(&quot;0.2&quot;), decimal(&quot;0.3&quot;));
   assert_eq!(decimal(BIGS[0]) + decimal(BIGS[1]), decimal(BIGS[2]));
   assert_eq!(decimal(BIGS[1]) + decimal(BIGS[0]), decimal(BIGS[2]));
}

#[test]
//#[ignore]
fn test_sub() {
   assert_eq!(decimal(BIGS[2]) - decimal(BIGS[1]), decimal(BIGS[0]));
   assert_eq!(decimal(BIGS[2]) - decimal(BIGS[0]), decimal(BIGS[1]));
}

#[test]
//#[ignore]
fn test_mul() {
   for big in BIGS.iter() {
       assert_eq!(decimal(big) * decimal(&quot;2&quot;), decimal(big) + decimal(big));
   }
}

// test identities
#[test]
//#[ignore]
fn test_add_id() {
   assert_eq!(decimal(&quot;1.0&quot;) + decimal(&quot;0.0&quot;), decimal(&quot;1.0&quot;));
   assert_eq!(decimal(&quot;0.1&quot;) + decimal(&quot;0.0&quot;), decimal(&quot;0.1&quot;));
   assert_eq!(decimal(&quot;0.0&quot;) + decimal(&quot;1.0&quot;), decimal(&quot;1.0&quot;));
   assert_eq!(decimal(&quot;0.0&quot;) + decimal(&quot;0.1&quot;), decimal(&quot;0.1&quot;));
}

#[test]
//#[ignore]
fn test_sub_id() {
   assert_eq!(decimal(&quot;1.0&quot;) - decimal(&quot;0.0&quot;), decimal(&quot;1.0&quot;));
   assert_eq!(decimal(&quot;0.1&quot;) - decimal(&quot;0.0&quot;), decimal(&quot;0.1&quot;));
}

#[test]
//#[ignore]
fn test_mul_id() {
   assert_eq!(decimal(&quot;2.1&quot;) * decimal(&quot;1.0&quot;), decimal(&quot;2.1&quot;));
   assert_eq!(decimal(&quot;1.0&quot;) * decimal(&quot;2.1&quot;), decimal(&quot;2.1&quot;));
}

#[test]
//#[ignore]
fn test_gt_positive_and_zero() {
   assert!(decimal(&quot;1.0&quot;) &gt; decimal(&quot;0.0&quot;));
   assert!(decimal(&quot;0.1&quot;) &gt; decimal(&quot;0.0&quot;));
}

#[test]
//#[ignore]
fn test_gt_negative_and_zero() {
   assert!(decimal(&quot;0.0&quot;) &gt; decimal(&quot;-0.1&quot;));
   assert!(decimal(&quot;0.0&quot;) &gt; decimal(&quot;-1.0&quot;));
}

// tests of arbitrary precision behavior
#[test]
//#[ignore]
fn test_add_uneven_position() {
   assert_eq!(decimal(&quot;0.1&quot;) + decimal(&quot;0.02&quot;), decimal(&quot;0.12&quot;));
}

#[test]
//#[ignore]
fn test_eq_vary_sig_digits() {
   assert!(decimal(&quot;0&quot;) == decimal(&quot;0000000000000.0000000000000000000000&quot;));
   assert!(decimal(&quot;1&quot;) == decimal(&quot;00000000000000001.000000000000000000&quot;));
}

#[test]
//#[ignore]
fn test_add_vary_precision() {
   assert_eq!(
       decimal(&quot;100000000000000000000000000000000000000000000&quot;)
           + decimal(&quot;0.00000000000000000000000000000000000000001&quot;),
       decimal(BIGS[0])
   )
}

#[test]
//#[ignore]
fn test_cleanup_precision() {
   assert_eq!(
       decimal(&quot;10000000000000000000000000000000000000000000000.999999999999999999999999998&quot;,)
           + decimal(
               &quot;10000000000000000000000000000000000000000000000.000000000000000000000000002&quot;,
           ),
       decimal(&quot;20000000000000000000000000000000000000000000001&quot;)
   )
}

#[test]
//#[ignore]
fn test_gt_varying_positive_precisions() {
   assert!(decimal(&quot;1.1&quot;) &gt; decimal(&quot;1.01&quot;));
   assert!(decimal(&quot;1.01&quot;) &gt; decimal(&quot;1.0&quot;));
   assert!(decimal(&quot;1.0&quot;) &gt; decimal(&quot;0.1&quot;));
   assert!(decimal(&quot;0.1&quot;) &gt; decimal(&quot;0.01&quot;));
}

#[test]
//#[ignore]
fn test_gt_positive_and_negative() {
   assert!(decimal(&quot;1.0&quot;) &gt; decimal(&quot;-1.0&quot;));
   assert!(decimal(&quot;1.1&quot;) &gt; decimal(&quot;-1.1&quot;));
   assert!(decimal(&quot;0.1&quot;) &gt; decimal(&quot;-0.1&quot;));
}

#[test]
//#[ignore]
fn test_gt_varying_negative_precisions() {
   assert!(decimal(&quot;-0.01&quot;) &gt; decimal(&quot;-0.1&quot;));
   assert!(decimal(&quot;-0.1&quot;) &gt; decimal(&quot;-1.0&quot;));
   assert!(decimal(&quot;-1.0&quot;) &gt; decimal(&quot;-1.01&quot;));
   assert!(decimal(&quot;-1.01&quot;) &gt; decimal(&quot;-1.1&quot;));
}

// test signed properties
#[test]
//#[ignore]
fn test_negatives() {
   assert!(Decimal::try_from(&quot;-1&quot;).is_some());
   assert_eq!(decimal(&quot;0&quot;) - decimal(&quot;1&quot;), decimal(&quot;-1&quot;));
   assert_eq!(decimal(&quot;5.5&quot;) + decimal(&quot;-6.5&quot;), decimal(&quot;-1&quot;));
}

#[test]
//#[ignore]
fn test_explicit_positive() {
   assert_eq!(decimal(&quot;+1&quot;), decimal(&quot;1&quot;));
   assert_eq!(decimal(&quot;+2.0&quot;) - decimal(&quot;-0002.0&quot;), decimal(&quot;4&quot;));
}

#[test]
//#[ignore]
fn test_multiply_by_negative() {
   assert_eq!(decimal(&quot;5&quot;) * decimal(&quot;-0.2&quot;), decimal(&quot;-1&quot;));
   assert_eq!(decimal(&quot;-20&quot;) * decimal(&quot;-0.2&quot;), decimal(&quot;4&quot;));
}

#[test]
//#[ignore]
fn test_simple_partial_cmp() {
   assert!(decimal(&quot;1.0&quot;) &lt; decimal(&quot;1.1&quot;));
   assert!(decimal(&quot;0.00000000000000000000001&quot;) &gt; decimal(&quot;-20000000000000000000000000000&quot;));
}

// test carrying rules
// these tests are designed to ensure correctness of implementations for which the
// integer and fractional parts of the number are stored separately
#[test]
//#[ignore]
fn test_carry_into_integer() {
   assert_eq!(decimal(&quot;0.901&quot;) + decimal(&quot;0.1&quot;), decimal(&quot;1.001&quot;))
}

#[test]
//#[ignore]
fn test_carry_into_fractional_with_digits_to_right() {
   assert_eq!(decimal(&quot;0.0901&quot;) + decimal(&quot;0.01&quot;), decimal(&quot;0.1001&quot;))
}

#[test]
//#[ignore]
fn test_add_carry_over_negative() {
   assert_eq!(decimal(&quot;-1.99&quot;) + decimal(&quot;-0.01&quot;), decimal(&quot;-2.0&quot;))
}

#[test]
//#[ignore]
fn test_sub_carry_over_negative() {
   assert_eq!(decimal(&quot;-1.99&quot;) - decimal(&quot;0.01&quot;), decimal(&quot;-2.0&quot;))
}

#[test]
//#[ignore]
fn test_add_carry_over_negative_with_fractional() {
   assert_eq!(decimal(&quot;-1.99&quot;) + decimal(&quot;-0.02&quot;), decimal(&quot;-2.01&quot;))
}

#[test]
//#[ignore]
fn test_sub_carry_over_negative_with_fractional() {
   assert_eq!(decimal(&quot;-1.99&quot;) - decimal(&quot;0.02&quot;), decimal(&quot;-2.01&quot;))
}

#[test]
//#[ignore]
fn test_carry_from_rightmost_one() {
   assert_eq!(decimal(&quot;0.09&quot;) + decimal(&quot;0.01&quot;), decimal(&quot;0.1&quot;))
}

#[test]
//#[ignore]
fn test_carry_from_rightmost_more() {
   assert_eq!(decimal(&quot;0.099&quot;) + decimal(&quot;0.001&quot;), decimal(&quot;0.1&quot;))
}

#[test]
//#[ignore]
fn test_carry_from_rightmost_into_integer() {
   assert_eq!(decimal(&quot;0.999&quot;) + decimal(&quot;0.001&quot;), decimal(&quot;1.0&quot;))
}

// test arithmetic borrow rules
#[test]
//#[ignore]
fn test_add_borrow() {
   assert_eq!(decimal(&quot;0.01&quot;) + decimal(&quot;-0.0001&quot;), decimal(&quot;0.0099&quot;))
}

#[test]
//#[ignore]
fn test_sub_borrow() {
   assert_eq!(decimal(&quot;0.01&quot;) - decimal(&quot;0.0001&quot;), decimal(&quot;0.0099&quot;))
}

#[test]
//#[ignore]
fn test_add_borrow_integral() {
   assert_eq!(decimal(&quot;1.0&quot;) + decimal(&quot;-0.01&quot;), decimal(&quot;0.99&quot;))
}

#[test]
//#[ignore]
fn test_sub_borrow_integral() {
   assert_eq!(decimal(&quot;1.0&quot;) - decimal(&quot;0.01&quot;), decimal(&quot;0.99&quot;))
}

#[test]
//#[ignore]
fn test_add_borrow_integral_zeroes() {
   assert_eq!(decimal(&quot;1.0&quot;) + decimal(&quot;-0.99&quot;), decimal(&quot;0.01&quot;))
}

#[test]
//#[ignore]
fn test_sub_borrow_integral_zeroes() {
   assert_eq!(decimal(&quot;1.0&quot;) - decimal(&quot;0.99&quot;), decimal(&quot;0.01&quot;))
}

#[test]
//#[ignore]
fn test_borrow_from_negative() {
   assert_eq!(decimal(&quot;-1.0&quot;) + decimal(&quot;0.01&quot;), decimal(&quot;-0.99&quot;))
}

#[test]
//#[ignore]
fn test_add_into_fewer_digits() {
   assert_eq!(decimal(&quot;0.011&quot;) + decimal(&quot;-0.001&quot;), decimal(&quot;0.01&quot;))
}

// misc tests of arithmetic properties
#[test]
//#[ignore]
fn test_sub_into_fewer_digits() {
   assert_eq!(decimal(&quot;0.011&quot;) - decimal(&quot;0.001&quot;), decimal(&quot;0.01&quot;))
}

#[test]
//#[ignore]
fn test_add_away_decimal() {
   assert_eq!(decimal(&quot;1.1&quot;) + decimal(&quot;-0.1&quot;), decimal(&quot;1.0&quot;))
}

#[test]
//#[ignore]
fn test_sub_away_decimal() {
   assert_eq!(decimal(&quot;1.1&quot;) - decimal(&quot;0.1&quot;), decimal(&quot;1.0&quot;))
}

#}</code></pre></pre>
<a class="header" href="#4-答案" id="4-答案"><h2>4. 答案</h2></a>
<p><details></p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
use std::cmp::Ordering;
use std::fmt;
use std::ops::{Add, Mul, Sub};

#[macro_use]
extern crate try_opt;

extern crate num_bigint;
use num_bigint::BigInt;
extern crate num_traits;
use num_traits::pow;

/// Type implementing arbitrary-precision decimal arithmetic
#[derive(Debug, Eq, Clone)]
pub struct Decimal {
   digits: BigInt,
   decimal_index: usize,
}

impl Decimal {
   fn new(digits: BigInt, decimal_index: usize) -&gt; Decimal {
       let mut value = Decimal {
           digits: digits,
           decimal_index: decimal_index,
       };
       value.reduce();
       value
   }

   pub fn try_from(mut input: &amp;str) -&gt; Option&lt;Decimal&gt; {
       // clear extraneous whitespace
       input = input.trim();

       // don't bother to trim extraneous zeroes
       // leave it to users to manage their own memory

       // now build a representation of the number to parse
       let mut digits = String::with_capacity(input.len());
       let mut decimal_index = None;
       for ch in input.chars() {
           match ch {
               '0'...'9' | '-' | '+' =&gt; {
                   digits.push(ch);
                   if let Some(idx) = decimal_index.as_mut() {
                       *idx += 1;
                   }
               }
               '.' =&gt; {
                   if decimal_index.is_some() {
                       return None;
                   }
                   decimal_index = Some(0)
               }
               _ =&gt; return None,
           }
       }
       Some(Decimal::new(
           try_opt!(digits.parse::&lt;BigInt&gt;().ok()),
           match decimal_index {
               Some(idx) =&gt; idx,
               None =&gt; 0,
           },
       ))
   }

   /// Add precision to the less-precise value until precisions match
   ///
   /// Precision, in this case, is defined as the decimal index.
   fn equalize_precision(mut one: &amp;mut Decimal, mut two: &amp;mut Decimal) {
       fn expand(lower_precision: &amp;mut Decimal, higher_precision: &amp;Decimal) {
           let precision_difference =
               (higher_precision.decimal_index - lower_precision.decimal_index) as usize;

           lower_precision.digits =
               &amp;lower_precision.digits * pow(BigInt::from(10_usize), precision_difference);
           lower_precision.decimal_index += precision_difference;
       }
       if one.decimal_index &lt; two.decimal_index {
           expand(&amp;mut one, &amp;two)
       } else if one.decimal_index &gt; two.decimal_index {
           expand(&amp;mut two, &amp;one)
       }
       assert_eq!(one.decimal_index, two.decimal_index);
   }

   /// Eliminate extraneous trailing zeroes
   ///
   /// This reduces the decimal index, so that the raw values are easier to parse
   fn reduce(&amp;mut self) {
       let extra_zeroes = self.digits
           .to_string() // produce a decimal representation
           .chars()
           .rev() // trailing values
           .take(self.decimal_index) // not counting past the decimal point
           .take_while(|&amp;c| c == '0') // counting only `0` digits
           .count();
       self.digits = &amp;self.digits / pow(BigInt::from(10_usize), extra_zeroes);
       self.decimal_index -= extra_zeroes;
   }
}

macro_rules! auto_impl_decimal_ops {
   ($trait:ident, $func_name:ident, $digits_operation:expr, $index_operation:expr) =&gt; {
       impl $trait for Decimal {
           type Output = Self;
           fn $func_name(mut self, mut rhs: Self) -&gt; Self {
               Decimal::equalize_precision(&amp;mut self, &amp;mut rhs);
               Decimal::new(
                   $digits_operation(self.digits, rhs.digits),
                   $index_operation(self.decimal_index, rhs.decimal_index),
               )
           }
       }
   };
}

auto_impl_decimal_ops!(Add, add, |s, o| s + o, |s, _| s);
auto_impl_decimal_ops!(Sub, sub, |s, o| s - o, |s, _| s);
auto_impl_decimal_ops!(Mul, mul, |s, o| s * o, |s, o| s + o);

macro_rules! auto_impl_decimal_cow {
   ($trait:ident, $func_name:ident, $digits_operation:expr, $return_type:ty) =&gt; {
       impl $trait for Decimal {
           fn $func_name(&amp;self, other: &amp;Self) -&gt; $return_type {
               if self.decimal_index == other.decimal_index {
                   $digits_operation(&amp;self.digits, &amp;other.digits)
               } else {
                   // if we're here, the decimal indexes are unmatched.
                   // We have to compare equal terms.
                   // clone both sides so we can modify either of them as necessary.
                   // not efficient, but whatever.
                   let mut one = self.clone();
                   let mut two = other.clone();
                   Decimal::equalize_precision(&amp;mut one, &amp;mut two);
                   one.$func_name(&amp;two)
               }
           }
       }
   };
}

auto_impl_decimal_cow!(PartialEq, eq, |a, b| a == b, bool);
auto_impl_decimal_cow!(Ord, cmp, |a: &amp;BigInt, b: &amp;BigInt| a.cmp(b), Ordering);

impl PartialOrd for Decimal {
   fn partial_cmp(&amp;self, other: &amp;Decimal) -&gt; Option&lt;Ordering&gt; {
       Some(self.cmp(other))
   }
}

impl fmt::Display for Decimal {
   fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
       // get a representation of the pure digits,
       // left-padded with zeroes
       let digits = format!(&quot;{:0&gt;width$}&quot;, self.digits, width = self.decimal_index);
       if self.decimal_index == digits.len() {
           write!(f, &quot;0.{}&quot;, digits)
       } else if self.decimal_index == 0 {
           write!(f, &quot;{}&quot;, digits)
       } else {
           let (before_index, after_index) = digits.split_at(digits.len() - self.decimal_index);
           write!(f, &quot;{}.{}&quot;, before_index, after_index)
       }
   }
}

#[cfg(test)]
mod tests {
   use super::*;

   #[test]
   fn test_display_temp() {
       for test_str in vec![&quot;0&quot;, &quot;1&quot;, &quot;20&quot;, &quot;0.3&quot;, &quot;0.04&quot;, &quot;50.05&quot;, &quot;66.0006&quot;, &quot;0.007&quot;] {
           println!(
               &quot;Decimal representation of \&quot;{}\&quot;: {}&quot;,
               test_str,
               Decimal::try_from(test_str).expect(&quot;This should always become a decimal&quot;)
           );
           assert_eq!(
               test_str,
               Decimal::try_from(test_str)
                   .expect(&quot;This should always become a decimal&quot;)
                   .to_string()
           )
       }
   }
}

#}</code></pre></pre>
<p></details></p>
<hr />
<hr />
<a class="header" href="#填充相关" id="填充相关"><h2>填充/相关</h2></a>

                </main>

                <nav class="nav-wrapper" aria-label="Page navigation">
                    <!-- Mobile navigation buttons -->
                    
                    <a rel="prev" href="../scale-generator/README.zh.html" class="mobile-nav-chapters previous" title="Previous chapter"
                        aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>
                    

                    
                    <a rel="next" href="../anagram/README.zh.html" class="mobile-nav-chapters next" title="Next chapter"
                        aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
                    

                    <div style="clear: both"></div>
                </nav>
            </div>
        </div>

        <nav class="nav-wide-wrapper" aria-label="Page navigation">
            
            <a href="../scale-generator/README.zh.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter"
                aria-keyshortcuts="Left">
                <i class="fa fa-angle-left"></i>
            </a>
            

            
            <a href="../anagram/README.zh.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter"
                aria-keyshortcuts="Right">
                <i class="fa fa-angle-right"></i>
            </a>
            
        </nav>

    </div>

    

    
    <!-- Google Analytics Tag -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-128555056-1"></script>
    
    <script type="text/javascript">
        var localAddrs = ["localhost", "127.0.0.1", ""];
        if (localAddrs.indexOf(document.location.hostname) === -1) {
            window.dataLayer = window.dataLayer || [];
            function gtag() { dataLayer.push(arguments); }
            gtag('js', new Date());

            gtag('config', 'UA-128555056-1');
        }
    </script>
    

    
    <script src="../ace.js" type="text/javascript" charset="utf-8"></script>
    <script src="../editor.js" type="text/javascript" charset="utf-8"></script>
    <script src="../mode-rust.js" type="text/javascript" charset="utf-8"></script>
    <script src="../theme-dawn.js" type="text/javascript" charset="utf-8"></script>
    <script src="../theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
    

    
    <script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
    

    <script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
    <script src="../book.js" type="text/javascript" charset="utf-8"></script>

    <!-- Custom JS scripts -->
    

    

</body>

</html>